package io.bluefw.microapp.auth.resource;

import java.security.SecureRandom;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.shiro.crypto.hash.Sha512Hash;
import org.apache.shiro.util.ByteSource;

import io.bluefw.microapp.auth.bundle.BlueAuthBundle;
import io.bluefw.microapp.auth.domain.Account;
import io.bluefw.microapp.auth.repository.AccountDAO;
import io.dropwizard.hibernate.UnitOfWork;
import io.dropwizard.jersey.params.LongParam;

@Path("/auth/account")
@Produces(MediaType.APPLICATION_JSON)
public class AccountResource {
    private final AccountDAO accountDAO;

    public AccountResource(AccountDAO accountDAO) {
        this.accountDAO = accountDAO;
    }
    
    @POST    
    @UnitOfWork
    public Account create(Account account) {
    	return accountDAO.persist(account);
    }
    
    @PUT  
    @UnitOfWork
    public void update(Account account) {
    	accountDAO.persist(account);
    }
    
    @GET
    @Path("{id}")   
    @UnitOfWork
    public Account find(@PathParam("id") LongParam id) {
        return accountDAO.findById(id.get());
    }
    
    @GET
    @UnitOfWork
    public List<Account> list() {
        return accountDAO.findAll();
    }
    
    @DELETE
    @Path("{id}")   
    @UnitOfWork
    public void delete(@PathParam("id") LongParam id) {
    	accountDAO.delete(id.get());
    }
    
	@UnitOfWork
	@POST
	@Consumes("application/x-www-form-urlencoded")
	@Path("/register")
	public Response register(
			@FormParam("username") String username, 
			@FormParam("password") String password, 
			@FormParam("email") String email) {
	    String salt = Long.toString(new SecureRandom().nextLong());

	    Account account = new Account();
	    account.setName(username);
	    account.setEmail(email);
	    account.setSalt(salt);
	    account.setPassword(new Sha512Hash(password, ByteSource.Util.bytes(salt), BlueAuthBundle.HashIterations).toHex());

	    accountDAO.persist(account);
	    return Response.ok("").build();
	}
}
